Įvaldykite pažangų Django URL maršrutizavimą. Kurkite lanksčias, efektyvias programas, tvarkančias įvairias URL struktūras bei tarptautinius poreikius.
Django URL maršrutizavimas: sudėtingų šablonų derinimo įvaldymas tvirtoms žiniatinklio programoms
Django, aukšto lygio Python žiniatinklio karkasas, supaprastina sudėtingų žiniatinklio programų kūrimą. Kritinis bet kurios žiniatinklio programos komponentas yra jos URL maršrutizavimo sistema. Django URL dispečeris yra nepaprastai galingas, leidžiantis apibrėžti švarius, lengvai skaitomus ir prižiūrimus URL šablonus. Šis vadovas gilina į pažangias šablonų derinimo technikas Django URL maršrutizavime, suteikdamas jums galimybę kurti labai lanksčias ir efektyvias žiniatinklio programas, tinkamas globaliai auditorijai. Išnagrinėsime reguliariuosius reiškinius, URL parametrus ir geriausią praktiką, kad jūsų maršrutizavimo sistema būtų patikima ir lengvai suprantama.
Django URL maršrutizavimo pagrindų supratimas
Prieš pradedant gilintis į pažangų šablonų derinimą, prisiminkime pagrindus. Django naudoja URL dispečerį, kuris susieja URL šablonus su konkrečiais vaizdais (views). Šie vaizdai apdoroja logiką ir atvaizduoja turinį tam tikram URL. URL šablonai apibrėžiami Python faile, pavadintame urls.py
, kuris paprastai yra jūsų Django programos ar projekto kataloge.
Paprastas URL šablonas atrodo taip:
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003_view),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
Šiame pavyzdyje:
path()
yra funkcija, naudojama URL šablonui apibrėžti.- Pirmasis
path()
argumentas yra pats URL šablonas, kuris gali apimti tiesiogines eilutes arba šablonus, naudojant kampinius skliaustus (<...>
), norint užfiksuoti URL dalis. - Antrasis argumentas yra vaizdo funkcija, kuri bus iškviesta, kai URL atitiks šabloną.
Reguliarieji reiškiniai Django URL šablonuose
Nors Django siūlo įmontuotus konverterius (pvz., <int:year>
ir <slug:slug>
), dažnai reikia detalesnės kontrolės jūsų URL šablonams. Štai čia praverčia reguliarieji reiškiniai (regex). Reguliarieji reiškiniai leidžia apibrėžti sudėtingus šablonus, atitinkančius įvairias URL struktūras. Django funkcija re_path()
, importuota iš django.urls
, naudojama URL šablonų apibrėžimui naudojant reguliariuosius reiškinius.
Štai kaip galite naudoti re_path()
:
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'^articles/([0-9]{4})/$', views.year_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
]
Šiame pavyzdyje:
re_path()
pirmuoju argumentu priima neapdorotą eilutę (r''
), kurioje yra reguliarusis reiškinys.^
atitinka URL pradžią.$
atitinka URL pabaigą.([0-9]{4})
atitinka lygiai keturis skaitmenis ir užfiksuoja juos kaip grupę. Ši užfiksuota grupė tada perduodama kaip argumentas jūsų vaizdo funkcijai.- Skaitmeniniai skliaustai
()
naudojami apibrėžti fiksavimo grupes reguliariajame reiškinyje. Šios grupės perduodamos kaip poziciniai argumentai vaizdui.
Apsvarstykite pasaulinę elektroninės prekybos svetainę. Galite naudoti regex, kad atitiktų produktų URL, leidžiant skirtingas pavadinimų konvencijas ir produktų kodus:
re_path(r'^products/(?P<product_code>[A-Z]{3}-[0-9]{3})/(?P<product_name>[a-z-]+)/$', views.product_detail),
Šiuo atveju URL /products/ABC-123/red-widget/
atitiktų, o vaizdas product_detail
gautų užfiksuotas grupes, pavadintas 'product_code' ir 'product_name', kaip raktažodžių argumentus.
Pavadinimų grupės reguliariuosiuose reiškiniuose
Dirbant su reguliariaisiais reiškiniais, dažnai yra lengviau skaityti ir prižiūrėti kodą, naudojant pavadintas grupes, o ne pozicinius argumentus. Pavadintos grupės leidžia jums kreiptis į užfiksuotas grupes pagal pavadinimą jūsų vaizdo funkcijose.
Norėdami naudoti pavadintas grupes, reguliariajame reiškinyje naudokite sintaksę (?P<name>pattern)
:
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
]
Šiame pavyzdyje month_archive
vaizdo funkcija gautų užfiksuotus metus ir mėnesį kaip raktažodžių argumentus: year=2023, month=12
. Tai daro vaizdo kodą daug švaresnį ir lengviau suprantamą.
Integruoti URL konverteriai: patogi alternatyva
Django siūlo įvairius įmontuotus URL konverterius, kurie gali supaprastinti jūsų URL šablonus ir padaryti juos lengviau skaitomus, ypač įprastais atvejais. Šie konverteriai yra glaustesni nei reguliarieji reiškiniai paprastais atvejais.
Štai keletas įmontuotų konverterių:
str
: Atitinka bet kokią ne tuščią eilutę (išskyrus kelio atskyrimo simbolį, '/').int
: Atitinka vieną ar daugiau skaitmenų.slug
: Atitinka „slug“, kuris paprastai yra eilutė, sudaryta iš raidžių, skaičių, brūkšnelių ir pabraukimo ženklų.uuid
: Atitinka UUID (Universaliai Unikalų Identifikatorių).path
: Atitinka bet kokią ne tuščią kelio eilutę (įskaitant kelio atskyrimo simbolį, '/').
Pavyzdys, naudojant integruotus konverterius:
from django.urls import path
from . import views
urlpatterns = [
path('blog/post/<slug:post_slug>/', views.post_detail, name='post_detail'),
path('products/<int:product_id>/', views.product_detail, name='product_detail'),
]
Integruotų konverterių naudojimas dažniausiai yra geresnis pasirinkimas, kai jie atitinka jūsų poreikius, nes juos lengviau skaityti ir prižiūrėti.
URL šablonų tvarka ir pirmenybė
Jūsų URL šablonų tvarka faile urls.py
yra labai svarbi. Django apdoroja šablonus tokia tvarka, kokia jie yra apibrėžti, sustodamas prie pirmojo atitikimo. Jei turite persidengiančius šablonus, tvarka nulems, kuris vaizdas bus iškviestas. Pavyzdžiui, apsvarstykite šiuos šablonus:
urlpatterns = [
path('articles/create/', views.article_create),
path('articles/<int:article_id>/', views.article_detail),
]
Jei šablonas straipsnio kūrimui (/articles/create/
) yra patalpintas po šablonu, skirtu konkrečiam straipsniui rodyti (/articles/<int:article_id>/
), „create“ URL gali būti neteisingai atitiktas pagal <int:article_id>
šabloną, o tai sukels netikėtą elgesį. Visada patalpinkite konkretesnius šablonus *prieš* bendresnius šablonus.
URL vardų sritys ir atvirkštinis išskyrimas
Kai jūsų Django projektas auga, jūsų URL šablonai gali tapti sudėtingi. URL vardų sritys ir atvirkštinis išskyrimas padeda prižiūrėti jūsų URL ir pagerina kodo palaikymą.
URL vardų sritys
URL vardų sritys padeda išvengti pavadinimų konfliktų, kai turite kelias programas su panašiais URL šablonais. Jos suteikia būdą „apriboti“ jūsų URL šablonus. Norėdami naudoti vardų sritis, apvyniojate savo programos URL šablonus į URLconf
(paprastai projekto urls.py
faile):
from django.urls import include, path
urlpatterns = [
path('blog/', include(('blog.urls', 'blog'), namespace='blog')),
path('shop/', include(('shop.urls', 'shop'), namespace='shop')),
]
Šiame pavyzdyje „blog“ programos URL bus susieti su „blog“ vardų sritimi, o „shop“ programos URL – su „shop“ vardų sritimi. Tai padeda išvengti konfliktų, jei abi programos turi URL šabloną, pavadintą „detail“, pavyzdžiui. Į tinklaraščio detalės URL kreiptumėtės naudodami blog:detail
, o parduotuvės detalės URL – naudodami shop:detail
, kai naudojate {% url %}
šablono žymę (žr. žemiau) arba reverse()
funkciją (taip pat žemiau).
Atvirkštinis išskyrimas
Atvirkštinis išskyrimas (reverse resolution) yra URL generavimo iš vaizdo pavadinimo ir reikiamų parametrų procesas. Tai yra labai svarbu norint išlaikyti jūsų URL prižiūrimus. Jei pakeisite URL šabloną savo urls.py
faile, jums nereikės atnaujinti visų nuorodų savo šablonuose ar vaizduose; jums reikės atnaujinti tik URL šabloną. Django automatiškai atnaujins sugeneruotus URL.
Norėdami naudoti atvirkštinį išskyrimą, turite suteikti pavadinimą savo URL šablonams, naudodami name
argumentą:
from django.urls import path
from . import views
urlpatterns = [
path('articles/<int:pk>/', views.article_detail, name='article_detail'),
]
Savo šablonuose galite naudoti {% url %}
šablono žymę URL generavimui:
<a href="{% url 'article_detail' pk=article.pk %}">View Article</a>
Savo vaizduose galite naudoti reverse()
funkciją iš django.urls
:
from django.urls import reverse
def some_view(request, article_id):
url = reverse('article_detail', args=[article_id]) # Using positional arguments
# or
url = reverse('article_detail', kwargs={'pk': article_id}) # Using keyword arguments
# ...
Atvirkštinis išskyrimas žymiai pagerina jūsų Django programos palaikymą. Apsvarstykite daugiakalbę elektroninės prekybos svetainę. Jei produkto URL struktūra keičiasi priklausomai nuo kalbos ar regiono (pvz., pridedant kalbos kodą), jums reikia atnaujinti tik URL šablonus, o ne daugybę nuorodų visoje jūsų svetainėje.
Internacionalizacijos ir lokalizacijos valdymas URL maršrutizavime
Kuriant žiniatinklio programą globaliai auditorijai, internacionalizacija (i18n) ir lokalizacija (l10n) yra svarbiausios. Django teikia tvirtą paramą abiems. Jūsų URL maršrutizavimas gali būti pritaikytas palaikyti skirtingas kalbas ir regioninius nustatymus.
Kalbos prefiksai URL adresuose
Vienas dažnas metodas yra įtraukti kalbos kodą į URL. Django funkcija i18n_patterns()
(iš django.conf.urls.i18n
) supaprastina tai. Ji automatiškai prideda vartotojo pageidaujamos kalbos kodą prieš jūsų URL šablonus. Tam reikia, kad jūsų MIDDLEWARE
nustatymuose būtų aktyvuotas 'django.middleware.locale.LocaleMiddleware'
.
from django.conf.urls.i18n import i18n_patterns
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accounts.urls')),
]
urlpatterns += i18n_patterns(
path('', include('myapp.urls')),
# Add more patterns here
prefix_default_language=False, # Set to True to prefix default language also
)
Naudojant šią konfigūraciją, URL atrodys kaip /en/…
(anglų), /fr/…
(prancūzų) ir t.t. Django automatiškai apdoros kalbos derinimą pagal vartotojo naršyklės nustatymus ar kitas konfigūracijas. Tai leidžia svetainei dinamiškai rodyti turinį vartotojo pageidaujama kalba.
URL vertimas naudojant gettext
Django vertimo karkasas, naudojantis gettext
, leidžia versti tekstines eilutes jūsų URL. Galite apvynioti tekstines eilutes savo URL šablonuose funkcija gettext_lazy()
iš django.utils.translation
. Tai užtikrina, kad URL šablonas būtų tinkamai išverstas atvaizduojant puslapį. Įsitikinkite, kad jūsų settings.py
faile nustatytas USE_I18N = True
.
from django.urls import path
from django.utils.translation import gettext_lazy as _
from . import views
urlpatterns = [
path(_('about/'), views.about_view, name='about'), # Example translation
]
Kai vartotojo pageidaujama kalba yra, pavyzdžiui, prancūzų, eilutė _('about/')
bus išversta į prancūzų kalbos atitikmenį (pvz., '/a-propos/'
), užtikrinant lokalizuotą vartotojo patirtį. Nepamirškite paleisti python manage.py makemessages
, kad sugeneruotumėte vertimo failus.
Regionams būdingų duomenų tvarkymas
Regionui specifiniams duomenims, tokiems kaip skirtingas valiutos formatavimas ar datos formatai, galite naudoti Python `locale` modulį ir konfigūruoti savo šablonus su atitinkamais kalbos kodais, kad atitiktų lokalizuotus formatus.
Pažangios technikos ir aplinkybės
Pasirinktiniai URL konverteriai
Labai specifiniams ir nestandartiniams URL šablonams galite sukurti pasirinktinius URL konverterius. Tai yra klasės, apibrėžiančios, kaip konvertuoti užfiksuotą eilutę iš URL į Python objektą ir kaip konvertuoti tą objektą atgal į URL šablono eilutę. Pasirinktiniai konverteriai suteikia didžiausią lankstumą.
Štai pagrindinis pasirinktinio konverterio pavyzdys, kuris konvertuoja šešioliktainį spalvos kodą į spalvos objektą:
# In your app's urls.py
from django.urls import register_converter
class HexColorConverter:
regex = r'[0-9a-fA-F]{6}'
def to_python(self, value):
return value # Or convert to a Color object if needed
def to_url(self, value):
return value.lower() # Ensure consistent lowercase for URL
register_converter(HexColorConverter, 'hexcolor')
Dabar, jūsų urls.py
faile:
from django.urls import path
from . import views
urlpatterns = [
path('colors/<hexcolor:color_code>/', views.color_detail, name='color_detail'),
]
Vaizdas color_detail
dabar gaus šešioliktainį spalvos kodą kaip eilutę.
URL šablonų testavimas
Kruopštus URL šablonų testavimas yra labai svarbus siekiant užtikrinti, kad jie veiktų taip, kaip tikimasi. Django suteikia testavimo karkasą, leidžiantį rašyti testus, kurie patikrina, ar jūsų URL išsprendžiami į tinkamus vaizdus su tinkamais parametrais. Naudokite Django testavimo įrankius, kad rašytumėte vienetų testus ir integracijos testus, kad patvirtintumėte savo maršrutizavimo logiką. Tai padeda anksti aptikti klaidas ir išvengti netikėto elgesio.
Paprasto testo pavyzdys:
from django.test import Client, TestCase
from django.urls import reverse
class URLTests(TestCase):
def test_article_detail_url(self):
url = reverse('article_detail', kwargs={'pk': 123})
response = self.client.get(url)
self.assertEqual(response.status_code, 200) # Or another appropriate response
Saugumo aspektai
Kuriant URL šablonus, atsižvelkite į saugumo aspektus. Pavyzdžiui:
- Įvesties validavimas: Visada patikrinkite įvestį iš URL parametrų, kad išvengtumėte įterpimo atakų. Naudokite Django įmontuotus mechanizmus, pvz., ribotą leidžiamų simbolių rinkinį ar reguliariuosius reiškinius, arba įmontuotus konverterius.
- CSRF apsauga: Įsitikinkite, kad įjungėte CSRF apsaugą visoms POST užklausoms, kurios modifikuoja duomenis.
- Užklausų ribojimas: Įdiekite užklausų ribojimą, kad apsaugotumėte nuo paslaugos atsisakymo (DoS) atakų.
Geriausia praktika Django URL maršrutizavimui
Šių geriausių praktikų laikymasis padės jums sukurti prižiūrimą ir keičiamo dydžio Django programą:
- Išlaikykite URL švarius ir lengvai skaitomus: Siekite URL, kurie būtų lengvai suprantami ir atspindėtų jūsų duomenų ir programos struktūrą.
- Naudokite prasmingus pavadinimus: Naudokite aiškius ir aprašomuosius pavadinimus savo URL šablonams ir vaizdų funkcijoms.
- Pasinaudokite integruotais konverteriais: Naudokite Django integruotus konverterius, kai tik įmanoma, kad jūsų URL šablonai būtų glausti.
- Naudokite vardų sritis: Organizuokite savo URL šablonus naudodami vardų sritis, ypač dirbdami su keliomis programomis.
- Naudokite atvirkštinį išskyrimą: Visada naudokite atvirkštinį išskyrimą (
reverse()
ir{% url %}
), kad generuotumėte URL. - Komentuokite savo kodą: Pridėkite komentarų prie savo
urls.py
failo, kad paaiškintumėte sudėtingus URL šablonus ar bet kokius dizaino sprendimus. - Kruopščiai testuokite: Rašykite išsamius testus, kad užtikrintumėte, jog jūsų URL šablonai veikia taip, kaip tikimasi.
- Laikykitės mažiausio nuostabos principo: Kurkite savo URL taip, kad jie veiktų taip, kaip vartotojai tikėtųsi.
- Atsižvelkite į SEO: Optimizuokite savo URL paieškos sistemoms. Naudokite susijusius raktažodžius savo URL keliuose ir kurkite žmogui suprantamus URL.
- Dokumentacija: Išsamiai dokumentuokite savo URL struktūrą ir šablonus, ypač išorinėms API. Naudokite įrankį, pvz., OpenAPI (Swagger), kad padėtumėte.
Pavyzdys: tinklaraščio kūrimas naudojant pažangų maršrutizavimą
Iliustruokime šias sąvokas praktiniu paprasto tinklaraščio kūrimo pavyzdžiu. Šis pavyzdys naudoja įmontuotų konverterių, pavadintų grupių ir atvirkštinio išskyrimo derinį.
Pirmiausia apibrėžkite savo modelius (supaprastinta aiškumo dėlei):
# models.py
from django.db import models
from django.utils.text import slugify
class Author(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True, blank=True, null=True)
def __str__(self):
return self.name
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
super().save(*args, **kwargs)
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True, blank=True, null=True)
content = models.TextField()
author = models.ForeignKey(Author, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, blank=True, null=True)
published_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)
Tada sukurkite savo urls.py
failą tinklaraščio programai:
# urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.post_list, name='post_list'),
path('post/<slug:slug>/', views.post_detail, name='post_detail'),
path('category/<slug:slug>/', views.category_detail, name='category_detail'),
path('author/<int:pk>/', views.author_detail, name='author_detail'),
]
Dabar apibrėžkite vaizdus savo views.py
faile:
# views.py
from django.shortcuts import render, get_object_or_404
from .models import Post, Category, Author
def post_list(request):
posts = Post.objects.all().order_by('-published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, slug):
post = get_object_or_404(Post, slug=slug)
return render(request, 'blog/post_detail.html', {'post': post})
def category_detail(request, slug):
category = get_object_or_404(Category, slug=slug)
posts = Post.objects.filter(category=category).order_by('-published_date')
return render(request, 'blog/category_detail.html', {'category': category, 'posts': posts})
def author_detail(request, pk):
author = get_object_or_404(Author, pk=pk)
posts = Post.objects.filter(author=author).order_by('-published_date')
return render(request, 'blog/author_detail.html', {'author': author, 'posts': posts})
Šiame pavyzdyje kiekvienas URL šablonas naudoja aprašomąjį pavadinimą (pvz., post_detail
, category_detail
, author_detail
) ir įmontuotų konverterių (<slug:slug>
, <int:pk>
) derinį. „Slug“ konverteris naudojamas įrašo, kategorijos ir autoriaus vaizdams, o „int“ konverteris – autoriaus vaizdui.
Norėdami susieti su įrašo detalės puslapiu savo šablone:
<a href="{% url 'blog:post_detail' slug=post.slug %}">{{ post.title }}</a>
Dalis `blog:post_detail` pasinaudoja vardų sritimi, kurią deklaravome pagrindiniame projekto URLconf (žr. skyrių apie vardų sritis), o slug=post.slug
pateikia reikiamus parametrus. Šis pavyzdys demonstruoja atvirkštinio išskyrimo privalumus. Jei įrašų URL struktūra pasikeičia, reikia atnaujinti tik URL šablonus, o šablonų nuorodos lieka nepakitusios.
Išvada: Django URL maršrutizavimo galios išnaudojimas
Django URL maršrutizavimo sistema yra pagrindinis tvirtų ir prižiūrimų žiniatinklio programų kūrimo aspektas. Šis vadovas apėmė pagrindinius pažangaus šablonų derinimo principus, įskaitant reguliariuosius reiškinius, pavadintas grupes, integruotus konverterius, vardų sritis, atvirkštinį išskyrimą ir internacionalizaciją. Įvaldę šias technikas, galite sukurti lanksčias, gerai struktūrizuotas ir lengvai keičiamo dydžio žiniatinklio programas, tinkamas globaliai auditorijai.
Visada prisiminkite teikti pirmenybę švariems URL, tinkamam pavadinimui ir kruopščiam testavimui, siekiant užtikrinti, kad jūsų programa būtų lengvai suprantama, prižiūrima ir plečiama. Su čia įgytais įgūdžiais ir žiniomis, esate gerai pasirengę kurti sudėtingas Django programas, kurios gali apdoroti įvairias URL struktūras ir palaikyti vartotojus visame pasaulyje. Nuolatinis mokymasis ir praktika yra būtini norint įvaldyti galingas Django URL maršrutizavimo galimybes. Eksperimentuokite su pasirinktiniais konverteriais, įtraukite internacionalizacijos funkcijas ir kurkite tvirtus testavimo rinkinius, kad užtikrintumėte, jog jūsų projektai yra pasirengę globalaus žiniatinklio iššūkiams.